<?php

namespace App\Api\Controllers\Glow;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

class NuonuoController extends BaseController{
    
    // 诺诺门店配置列表
    function nuonuo_list(Request $request){
        $user = $this->parseToken();
        $store_id = $request->get('store_id', '');

        $where = [];
        
        if ($store_id) {
            $where[] = ['store_id', '=', $store_id];
            $obj = DB::table('nuonuo_stores');
            $obj->where($where)->select();
            $this->t = $obj->count();
            $data = $this->page($obj)->get();
            $this->status = 1;
            $this->message = '数据返回成功';
            return $this->format($data);
        }else{
            return json_encode([
                "status" => 2,
                "message" => "缺少必要参数",
            ]);
        }
    }
    
    // 诺诺设为默认开票配置
    function nuonuo_set_default(Request $request){
        $store_id = $request->get('store_id', '');
        $nuonuo_id = $request->get('nuonuo_id', '');
        if(!$nuonuo_id || !$store_id){
            return json_encode([
                "status" => 2,
                "message" => "缺少参数, 请刷新后重试",
            ]);
        }
        $nuonuo = DB::table('nuonuo_stores')->where(['store_id' => $store_id, 'id' => $nuonuo_id])->first(); // 查找是否存在记录
        if($nuonuo){
            DB::table('nuonuo_stores')->where(['store_id' => $store_id, 'is_billing' => 1])->update(['is_billing' => 2]); // 删除门店默认开票状态
            DB::table('nuonuo_stores')->where(['id' => $nuonuo_id])->update(['is_billing' => 1]); // 设为门店默认开票
            
            return json_encode([
                "status" => 1,
                "message" => "操作成功",
            ]);
        }else{
            return json_encode([
                "status" => 2,
                "message" => "操作失败, 请刷新后重试",
            ]);
        }
    }
    
    // 删除诺诺开票配置
    function del_nuonuo(Request $request){
        $user = $this->parseToken();
        $nuonuo_id = $request->get('nuonuo_id', '');
        
        $nuonuo = DB::table('nuonuo_stores')->where(['id' => $nuonuo_id])->first();
        if ($nuonuo) {
            if($nuonuo->is_billing == 1){
                return json_encode([
                    "status" => 2,
                    "message" => "默认的开票配置不可删除",
                ]);
            }
            
            DB::table('nuonuo_stores')->where(['id' => $nuonuo_id])->delete();
            return json_encode([
                "status" => 1,
                "message" => "删除成功",
            ]);
        } else {
            return json_encode([
                "status" => 2,
                "message" => "删除失败, 请刷新后重试",
            ]);
        }
    }
    
    // 诺诺重新开票接口
    public function re_billing(Request $request){
        $orderNo = $request->get('out_trade_no', ''); // 订单号
        if(!$orderNo){
            return json_encode([
                'code' => 'E9999',
                'describe' => '订单号不存在'
            ]);
        }
        
        $order = Db::table('orders')->where([ 'out_trade_no' => $orderNo ])->first(); // 查询订单信息
        if(!$order){
            return json_encode([
                'code' => 'E9999',
                'describe' => '仅支持当日开票'
            ]);
        }

        if($order->pay_status!=1){
            return json_encode([
                'code' => 'E9999',
                'describe' => '仅支持支付成功的订单开票'
            ]);
        }

        $nuonuo_stores = DB::table('nuonuo_stores')->where(['store_id' => $order->store_id])->where(['is_billing' => 1])->first(); // 查找记录
        if(!$nuonuo_stores){
            return json_encode([
                'code' => 'E9999',
                'describe' => '商户未配置诺诺开票参数, 请先到代理商后台设置'
            ]);
        }
        /*
        $appKey = '13985881'; // appKey
        $appSecret = '5836FB60AB5A4D5D'; // appSecret
        */
        $appKey=$nuonuo_stores->app_id;
        $appSecret=$nuonuo_stores->app_secret;
        $salerTaxNum = $nuonuo_stores->userTax; // 销售方税号 150301199811285326
        $taxnum = $nuonuo_stores->userTax; // 授权商户的税号
        $token = $nuonuo_stores->access_token;
        if (empty($appKey) || empty($appSecret) || empty($token)) {
            return json_encode([
                'code' => 'E9999',
                'describe' => '商户未配置参数'
            ]);
        }
//        $method = "nuonuo.ElectronInvoice.reInvoice"; // 开票重试接口
        $method = "nuonuo.OpeMplatform.reInvoice";
        $body = json_encode([
            "orderno" => $orderNo, // aliscan20220804105945037182529
        ]);
        $url = "https://sdk.nuonuo.com/open/v1/services"; // https://sandbox.nuonuocs.cn/open/v1/services
        $senid = uniqid(); // generate your meaningful senid
        
        $res = $this->sendPostSyncRequest($url, $senid, $appKey, $appSecret, $token, $taxnum, $method, $body);
        Log::channel("invoice")->info("sendPostSyncRequest_reInvoice", [
            "config"=>[
                "appKey"=>$appKey,
                "appSecret"=>$appSecret,
                "token"=>$token,
                "method"=>$method
            ],
            "req" => $body,
            "res" => $res
        ]);
        return $res;
    }
    
    /**
     * 发送HTTP POST请求 <同步>
     * @param url       请求地址
     * @param senid     流水号
     * @param appKey    appKey
     * @param appSecret appSecret
     * @param token     授权码
     * @param taxnum    税号, 普通商户可不填
     * @param method    API名称
     * @param content   私有参数, 标准JSON格式
     * @throws NnuoException
     * @return 成功时返回，其他抛异常
     */
    public function sendPostSyncRequest($url, $senid, $appKey, $appSecret, $token,$taxnum, $method, $content, $timeOut = 6)
    {
        self::checkParam($senid, "senid不能为空");
        self::checkParam($token, "token不能为空");
        self::checkParam($appKey, "appKey不能为空");
        self::checkParam($method, "method不能为空");
        self::checkParam($url, "请求地址URL不能为空");
        self::checkParam($content, "content不能为空");
        self::checkParam($appSecret, "appSecret不能为空");
//        dump(3);die;
        try {
            $timestamp = time();
            $nonce = rand(10000, 1000000000);

            $finalUrl = "{$url}?senid={$senid}&nonce={$nonce}&timestamp={$timestamp}&appkey={$appKey}";

            $urlInfo = parse_url($url);
            if ($urlInfo === FALSE) {
                throw new NnuoException("url解析失败");
            }

            $sign = $this->makeSign($urlInfo["path"], $appSecret, $appKey, $senid, $nonce, $content, $timestamp);

            $headers = array(
                "Content-Type: application/json",
                "X-Nuonuo-Sign: {$sign}",
                "accessToken: {$token}",
                "userTax: {$taxnum}",
                "method: {$method}",
                "sdkVer: " . "2.0.0"
            );
//            print_r($headers);die;
            // 调用开放平台API
            return $this->postCurl($finalUrl, $content, $headers, $timeOut);
        } catch (Exception $e) {
            throw new NnuoException("发送HTTP请求异常:" . $e->getMessage());
        }
    }
    
    public static function checkParam($param, $errMsg){
        if(empty($param)) {
            throw new NnuoException($errMsg);
        }
    }
    
    /**
     * 计算签名
     *
     * @param path       请求地址
     * @param senid     流水号
     * @param appKey    appKey
     * @param appSecret appSecret
     * @param nonce     随机码
     * @param body    请求包体
     * @param timestamp    时间戳
     * @return 返回签名
     */
    public function MakeSign($path, $appSecret, $appKey, $senid, $nonce, $body, $timestamp)
    {
        $pieces = explode('/', $path);
        $signStr = "a={$pieces[3]}&l={$pieces[2]}&p={$pieces[1]}&k={$appKey}&i={$senid}&n={$nonce}&t={$timestamp}&f={$body}";

        $sign = base64_encode(hash_hmac("sha1", $signStr, $appSecret, true));
        return $sign;
    }
    
    /**
     * 以post方式发起http调用
     *
     * @param string $url  url
     * @param array $params post参数
     * @param int $second   url执行超时时间，默认30s
     * @throws NnuoException
     */
    private static function postCurl($url, $params, $headers = array(), $second = 30)
    {
        $ch = curl_init();
        $curlVersion = curl_version();

        //设置超时
        curl_setopt($ch, CURLOPT_TIMEOUT, $second);
        curl_setopt($ch,CURLOPT_URL, $url);
        curl_setopt($ch,CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($ch,CURLOPT_SSL_VERIFYHOST, FALSE);
        //设置header
        curl_setopt($ch, CURLOPT_HEADER, FALSE);
        //要求结果为字符串且输出到屏幕上
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);

        //post提交方式
        curl_setopt($ch, CURLOPT_POST, TRUE);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $params);

        if (!empty($headers)) {
            curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        }

        //运行curl
        $data = curl_exec($ch);
//        dump($data);die;
        //返回结果
        if($data) {
            curl_close($ch);
            return $data;
        } else {
            $error = curl_error($ch);
            curl_close($ch);
            throw new NnuoException("curl出错:$error");
        }
    }
    
    
}